package com.sunnada.weixin.util.weixinPay;



import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import net.qp234.weixin.entities.Article;
import net.qp234.weixin.entities.ResMusicMessage;
import net.qp234.weixin.entities.ResNewsMessage;
import net.qp234.weixin.entities.ResTextMessage;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class EObject2XML {
	private EObject2XML() {
	}

	public static String mapToXml(Map<?, ?> map) {
		xstream.alias("xml", map.getClass());
		xstream.alias("xml", Map.class);
		xstream.alias("xml", HashMap.class);
		xstream.alias("xml", HashMap.class);
		xstream.alias("xml", JSONObject.class);
		xstream.alias("xml", JSONArray.class);
		return xstream.toXML(map).replace("__", "_").replace("<map>", "").replace("</map>", "");
	}
	
	public static String textMessageToXml(ResTextMessage textMessage) {
		xstream.alias("xml", textMessage.getClass());
		return xstream.toXML(textMessage);
	}

	public static String musicMessageToXml(ResMusicMessage musicMessage) {
		xstream.alias("xml", musicMessage.getClass());
		return xstream.toXML(musicMessage);
	}

	public static String newsMessageToXml(ResNewsMessage resNewsMessage) {
		xstream.alias("xml", resNewsMessage.getClass());
		xstream.alias("item", (new Article()).getClass());
		return xstream.toXML(resNewsMessage);
	}

	private static XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")) {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				boolean cdata = false;

				@SuppressWarnings("rawtypes")
				public void startNode(String name, Class clazz) {
					super.startNode(name, clazz);
				}

				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write("<![CDATA[");
						writer.write(text);
						writer.write("]]>");
					} else {
						writer.write(text);
					}
				}
			};
		}
	});
	
	static {
		xstream.registerConverter(new Converter() {
			
			@SuppressWarnings("rawtypes")
			@Override
			public boolean canConvert(Class type) {
				return HashMap.class.equals(type);
			}
			
			@Override
			public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
				return null;
			}
			
			@SuppressWarnings("rawtypes")
			@Override
			public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext marshallingcontext) {
				Map map = (Map) source;  
				for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
					Entry entry = (Entry) iterator.next();  
					writer.startNode(entry.getKey().toString());
					writer.setValue(entry.getValue().toString());
					writer.endNode();
				}
			}
		});
	}
}
